using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.IO;
using System.Management;
//using SHDocVw;


namespace OfficeClip.OpenSource.Utility
{
    public enum LogState
    {
        None = 0,
        Pass = 1,
        Fail = 2,
        Warning = 3,
        Debug = 4,
        Title = 5,
        SubTitle = 6,
        Error = 7,
        FatalError = 8,
        Info = 9,
        Event = 10,
        Property = 11,
        Function = 12
    }

    public enum LogLevel
    {
        OFF = 0,
        FATAL = 1,
        ERROR = 2,
        WARNING = 3,
        INFO = 4,
        DEBUG = 5,
        ALL = 6
    }

    public class Constants
    {
        public static int LineNum = 0;
        public static bool IsError = false;
        public static string ErrorMessage = string.Empty;
        public static int SqlCommandTimeout = 480;

        public static string GetSetupDir()
        {
            System.Reflection.Assembly Asm = System.Reflection.Assembly.GetExecutingAssembly();
            return Path.GetDirectoryName(Asm.Location);
        }

        /// <summary>
        /// Comapres the two version numbers
        /// </summary>
        /// <param name="version1"></param>
        /// <param name="version2"></param>
        /// <exception cref="System.Exception">If the version syntax is incorrect</exception>
        /// <returns>+1 if version1 > version2, 0 if they are equal, -1 if version2 > version1</returns>
        public static int CompareVersion(string version1, string version2)
        {
            string[] aver1 = version1.Split(".".ToCharArray());
            string[] aver2 = version2.Split(".".ToCharArray());
            if ((aver1.Length != 3) || (aver2.Length != 3))
                throw new Exception("Invalid format");
            if (Convert.ToInt32(aver1[0]) > Convert.ToInt32(aver2[0]))
                return 1;
            if (Convert.ToInt32(aver1[0]) < Convert.ToInt32(aver2[0]))
                return -1;
            if (Convert.ToInt32(aver1[1]) > Convert.ToInt32(aver2[1]))
                return 1;
            if (Convert.ToInt32(aver1[1]) < Convert.ToInt32(aver2[1]))
                return -1;
            if (Convert.ToInt32(aver1[2]) > Convert.ToInt32(aver2[2]))
                return 1;
            if (Convert.ToInt32(aver1[2]) < Convert.ToInt32(aver2[2]))
                return -1;
            return 0;
        }

        // Checks if the OfficeClip instance of the sql express is present. Gotten from theblog
        // http://blogs.msdn.com/sqlexpress/
        public static bool IsSqlExpressPresent(string strInstance, Utility.Log log)
        {
            const string edition = "Express Edition";
            string instance = "MSSQL$" + strInstance.ToUpper();
            const int spLevel = 1;

            bool fCheckEdition = false;
            bool fCheckSpLevel = false;

            try
            {
                // Run a WQL query to return information about SKUNAME and SPLEVEL about installed instances
                // of the SQL Engine.
                ManagementObjectSearcher getSqlExpress =
                        new ManagementObjectSearcher("root\\Microsoft\\SqlServer\\ComputerManagement",
                        "select * from SqlServiceAdvancedProperty where SQLServiceType = 1 and ServiceName = '"
                        + instance + "' and (PropertyName = 'SKUNAME' or PropertyName = 'SPLEVEL')");

                // If nothing is returned, SQL Express isn't installed.
                if (getSqlExpress.Get().Count == 0)
                {
                    return false;
                }

                // If something is returned, verify it is the correct edition and SP level.
                foreach (ManagementObject sqlEngine in getSqlExpress.Get())
                {
                    if (sqlEngine["ServiceName"].ToString().Equals(instance))
                    {
                        switch (sqlEngine["PropertyName"].ToString())
                        {
                            case "SKUNAME":
                                // Check if this is Express Edition or Express Edition with Advanced Services
                                fCheckEdition = sqlEngine["PropertyStrValue"].ToString().Contains(edition);
                                break;

                            case "SPLEVEL":
                                // Check if the instance matches the specified level
                                fCheckSpLevel = int.Parse(sqlEngine["PropertyNumValue"].ToString()) >= spLevel;
                                //fCheckSpLevel = sqlEngine["PropertyNumValue"].ToString().Contains(spLevel);
                                break;
                        }
                    }
                }

                if (fCheckEdition & fCheckSpLevel)
                {
                    return true;
                }
                return false;
            }
            catch (ManagementException e)
            {
                if (log != null)
                {
                    log.Write(
                       Utility.LogState.Error,
                       "Database",
                       "Could not find OfficeClip instance of SqlExpress: " + e.ErrorCode + ", " + e.Message
                       );
                }
                return false;
            }
        }

        /// <summary>
        /// Creates a COM object given it's ProgID.
        /// </summary>
        /// <param name="sProgID">The ProgID to create</param>
        /// <returns>The newly created object, or null on failure.</returns>
        public static object COMCreateObject(string sProgID)
        {
            // We get the type using just the ProgID
            Type oType = Type.GetTypeFromProgID(sProgID);
            if (oType != null)
            {
                return Activator.CreateInstance(oType);
            }

            return null;
        }

        public static void MimimizeWindow(System.Diagnostics.Process process)
        {
            System.Int32 SW_MINIMIZE = 6;
            System.Diagnostics.Process[] myProcess = System.Diagnostics.Process.GetProcessesByName(process.ProcessName);
            System.IntPtr hwnd = myProcess[0].MainWindowHandle;
            ShowWindow(hwnd, SW_MINIMIZE);
        }

        public static void ProvideFullAccess(string folder)
        {
            // In vista this does not work as we need to get the SeSecurityPrivilege access. In the meantime
            // we have to ignore this in case of any exception
            try
            {
                System.Security.AccessControl.DirectorySecurity sec
                = Directory.GetAccessControl(folder);
                sec.SetSecurityDescriptorSddlForm("D:PAI(A;OICI;FA;;;WD)"); // Gives full access to all the files in this folder
                Directory.SetAccessControl(folder, sec);
            }
            catch
            {
            }
        }

         [DllImport("user32.dll")]
        private static extern Boolean ShowWindow(IntPtr hWnd, Int32 nCmdShow);

    }
}
